﻿using CinemaMaestro.BusinessLayer.Contracts;
using CinemaMaestro.Common.IocContainer;
using CinemaMaestro.DataLayer.Contracts.Entities;
using CinemaMaestro.ViewModels;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace CinemaMaestro.WebApi.Controllers
{
    public class ScreeningsController : ApiController
    {

        [HttpGet]
        [Route("api/screeningsForCinema/{cinemaId}")]
        public IHttpActionResult GetTodaysNextScreeningsForCinema(int cinemaId)
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Screenings.Read()
                .Where(x => x.Room.Cinema.Id == cinemaId).AsEnumerable()
                .Where(x => x.StartDate > DateTime.Now).OrderBy(x => x.StartDate).ToList();

            List<ScreeningViewModel> models = new List<ScreeningViewModel>();

            foreach (var model in list)
            {
                ScreeningViewModel screening = model;
                models.Add(screening);
            }

            return Ok(models);
        }

        [HttpGet]
        [Route("api/availableStartTimes/{roomId}/{startDate}/{movieId}")]
        public IHttpActionResult GetAvailableStartTimes(int roomId, DateTime startDate, int movieId)
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();

            var screeningsOnDayinRoom = businessUoW.Screenings.Read()
                .Where(x => x.Room.Id == roomId).AsEnumerable()
                .Where(x => (x.StartDate.Date == startDate.Date || x.EndDate.Date == startDate.Date)).ToList();

            var day = startDate.Date;
            var movie = businessUoW.Movies.Read().First(x => x.Id == movieId);

            var availableTimeSlots = new List<TimeSpan>();

            for (int i = 0; i < 24; i++)
            {
                DateTime time;
                
                time = new DateTime(day.Year, day.Month, day.Day, i, 0, 0);

                var endTime = time.AddMinutes(movie.Duration);

                bool found = false;
                foreach (var screening in screeningsOnDayinRoom)
                {

                    if ((time >= screening.StartDate && time <= screening.EndDate)
                        || (endTime >= screening.StartDate && endTime <= screening.EndDate))
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    availableTimeSlots.Add(time.TimeOfDay);
                }
            }

            return Ok(availableTimeSlots);
        }

        [HttpGet]
        public IHttpActionResult GetAllScreenings()
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();

            var list = businessUoW.Screenings.Read().ToList();

            List<ScreeningViewModel> models = new List<ScreeningViewModel>();

            foreach (var model in list)
            {
                ScreeningViewModel screening = model;
                models.Add(screening);
            }

            return Ok(models);
        }

        [HttpGet]
        public IHttpActionResult GetScreening(int id)
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();

            var screening = businessUoW.Screenings.Read().FirstOrDefault(x => x.Id == id);
            if (screening == null)
            {
                return NotFound();
            }
            ScreeningViewModel screeningVM = screening;
            return Ok(screeningVM);
        }

        [HttpPut]
        public IHttpActionResult UpdateScreening(ScreeningViewModel screeningVM)
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();
            Screening screening = screeningVM;
            businessUoW.Screenings.Update(screening);
            return Ok();
        }

        [HttpDelete]
        public IHttpActionResult DeleteScreening(int id)
        {
            var businessUow = Resolver.Get<IBusinessObjectFactory>();
            var hasDependencies = businessUow.Sales.SalesHasRelationWithScreening(id);
            if (hasDependencies)
            {
                return NotFound();
            }
            hasDependencies = businessUow.Reservations.ReservationHasRelationWithScreening(id);
            if (hasDependencies)
            {
                return NotFound();
            }
            var deleted = businessUow.Screenings.Delete(id);
            if (deleted)
            {
                return Ok();
            }
            return NotFound();
        }

        [HttpPost]
        public IHttpActionResult CreateScreening(ScreeningViewModel screeningVM)
        {
            var businessUoW = Resolver.Get<IBusinessObjectFactory>();
            Screening screening = screeningVM;
            businessUoW.Screenings.Create(screening);
            return Ok();
        }
    }
}
